package jmine.tec.rpc.server.entity;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jmine.tec.rpc.common.entity.EntityRepresentation;
import jmine.tec.rpc.server.base.RestServiceErrorMessages;
import jmine.tec.rpc.server.base.RpcServerException;
import bancosys.tec.persist.Persistable;

/**
 * This class is responsible to assign a relation between two classes. The first class must implements the EntityRepresentation interface
 * and the second must implements the Persistable interface.
 * 
 * @author fernando.silva
 */
public class EntityRestMapping {

    private Map<Class<? extends EntityRepresentation>, Class<? extends Persistable>> representationToEntityMap =
            new ConcurrentHashMap<Class<? extends EntityRepresentation>, Class<? extends Persistable>>();

    private Map<Class<? extends Persistable>, Class<? extends EntityRepresentation>> entityToRepresentationMap =
            new ConcurrentHashMap<Class<? extends Persistable>, Class<? extends EntityRepresentation>>();

    /**
     * Register a new pair of classes.
     * 
     * @param representation the representation class.
     * @param persistable the persistable class.
     */
    public void register(Class<? extends EntityRepresentation> representation, Class<? extends Persistable> persistable) {
        if (this.entityToRepresentationMap.containsKey(persistable)) {
            throw new RpcServerException(RestServiceErrorMessages.ALREADY_REGISTERED_CLASS_ERROR.create(persistable));
        }
        if (this.representationToEntityMap.containsKey(representation)) {
            throw new RpcServerException(RestServiceErrorMessages.ALREADY_REGISTERED_CLASS_ERROR.create(representation));
        }

        this.entityToRepresentationMap.put(persistable, representation);
        this.representationToEntityMap.put(representation, persistable);

    }

    /**
     * Get representation class given a persitable class.
     * 
     * @param persistable the persistable class.
     * @return the representation class.
     */
    public Class<? extends EntityRepresentation> getRepresentationFor(Class<? extends Persistable> persistable) {
        return this.entityToRepresentationMap.get(persistable);
    }

    /**
     * Get persistable class given a representation class.
     * 
     * @param representation the representation class.
     * @return the persistable class.
     */
    public Class<? extends Persistable> getEntityFor(Class<? extends EntityRepresentation> representation) {
        return this.representationToEntityMap.get(representation);
    }

}
